home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / uae-0.000 / uae-0 / uae-0.6.0 / mac.c < prev    next >
C/C++ Source or Header  |  1996-05-23  |  43KB  |  1,680 lines

  1.  /* 
  2.   * UAE - The Un*x Amiga Emulator
  3.   * 
  4.   * Mac port specific stuff
  5.   * 
  6.   * (c) 1996 Ernesto Corvi
  7.   */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <QDOffscreen.h>
  13. #include <Palettes.h>
  14. #include <Profiler.h>
  15. #include <Sound.h>
  16. #include <errno.h>
  17.  
  18. #include "mackbd.h"
  19. #include "config.h"
  20. #include "amiga.h"
  21. #include "options.h"
  22. #include "memory.h"
  23. #include "custom.h"
  24. #include "newcpu.h"
  25. #include "xwin.h"
  26. #include "keyboard.h"
  27. #include "keybuf.h"
  28.  
  29. #define kAppleMenuID    128
  30. #define kFileMenuID        129
  31. #define    kEditMenuID        130
  32. #define    kDrivesMenuID    131
  33. #define    kMemoryMenuID    132
  34. #define    kResMenuID        135
  35. #define    kRateMenuID        134
  36. #define    kVideoMenuID    133
  37.  
  38. #define kAboutDialogID    128
  39. #define kHardfileDialogID    129
  40. #define kQuitError 130
  41.  
  42. #define mTopLeft(r)        (((Point *)&(r))[0])
  43. #define mBotRight(r)    (((Point *)&(r))[1])
  44.  
  45. #define qd_CenterScreen 144
  46.  
  47. extern int quit_program;
  48.  
  49. static GDHandle curDevice;
  50. static int oldDepth=0;
  51. static Boolean macCursorState=true;
  52. int    use_quickdraw=true;
  53. short    filesys_vRefNum=0;
  54. static KeyMap keys;
  55. static Boolean redraw=true,diskInit=true;
  56. static int mBarState=1;
  57. static int RM=0;
  58. static int my_use_gfxlib=0;
  59. static int my_automount_uaedev=1;
  60. static int my_screen_res=3;
  61. static int my_use_quickdraw=1;
  62. static WindowPtr mywin;
  63. static RgnHandle gOldVisRgn;
  64. static short gOldMBarHeight;
  65. static Boolean    macDiskStatus[4];
  66. static GWorldPtr gOffscreenBuffer;
  67. static PixMapHandle gOffscreenPixels;
  68. static Rect gOffscreenRect,gDrawRect;    
  69. static unsigned char *gOffscreenBaseAddr;
  70. static unsigned long gOffscreenRowBytes;
  71. static PaletteHandle mypal;
  72. static int CenterScreen=0;
  73. static CTabHandle    myCTAB;
  74. static long screenH=0,screenV=0;
  75. static GrafPtr    dummyPort;
  76. extern SndChannelPtr newChannel;
  77. static unsigned long refresh;
  78. extern char *xlinebuffer;
  79. long int xcolors[4096];
  80.  
  81. struct vidbuf_description gfxvidinfo;
  82.  
  83.  /* Keyboard and mouse */
  84.  
  85. static int keystate[256];
  86.  
  87. int buttonstate[3];
  88. int lastmx, lastmy;
  89. int newmousecounters;
  90.  
  91. static int colors_allocated;
  92.  
  93. // Prototypes
  94. static void HandleMenu (long mSelect);
  95. static void macHandleCursors(void);
  96. static Boolean CheckForSetup (void);
  97. static void ParamAString( ConstStr255Param theStr);
  98. static void printStatusLine (void);
  99. static void Share_main(void);
  100. static void Share_ResolvePath (FSSpec *fSpec, char *path);
  101. // end Prototypes
  102.  
  103. static void my_setpalette(int count, int r, int g, int b)
  104. {    RGBColor mycolor;
  105.     
  106.     mycolor.red=r*1024;
  107.     mycolor.green=g*1024;
  108.     mycolor.blue=b*1024;
  109.     
  110.     if (count == 0 || count == 255) SetEntryColor(mypal, count, &mycolor);
  111.     else SetEntryColor(mypal, (~count & 0x000000ff), &mycolor);
  112. }
  113.  
  114. static int get_color(int r, int g, int b, xcolnr *cnp)
  115. {
  116.     if (colors_allocated == 256) return -1;
  117.     *cnp = colors_allocated;
  118.     my_setpalette(colors_allocated, doMask(r, 6, 0), doMask(g, 6, 0), doMask(b, 6, 0));
  119.     colors_allocated++;
  120.     return 1;
  121. }
  122.  
  123. static void init_colors(void)
  124. {
  125.     int rw = 5, gw = 5, bw = 5;
  126.     colors_allocated = 0;
  127.     
  128.     if (gfxvidinfo.pixbytes == 1)
  129.     alloc_colors256(get_color);
  130.     else
  131.     {    if (gfxvidinfo.pixbytes == 4) rw=gw=bw=8;
  132.         alloc_colors64k(rw, gw, bw, gw+bw, bw, 0);
  133.     }
  134. }
  135.  
  136. static void HideMenuBar(GrafPtr grafPort)
  137. {    Rect    menuRect={0,0,20,640};
  138.     RgnHandle newVisRgn;
  139.     GrafPtr savePort;
  140.     
  141.     GetPort(&savePort);
  142.     SetPort(grafPort);
  143.  
  144.         // save off vis region
  145.     gOldVisRgn = NewRgn();
  146.     CopyRgn(grafPort->visRgn, gOldVisRgn);
  147.  
  148.         // expand the vis region to the port rect
  149.     newVisRgn = NewRgn();
  150.     RectRgn(newVisRgn, &grafPort->portRect);
  151.     CopyRgn(newVisRgn, grafPort->visRgn);
  152.     DisposeRgn(newVisRgn);
  153.  
  154.     PaintRect(&menuRect);
  155.  
  156.     gOldMBarHeight = GetMBarHeight();
  157.     LMSetMBarHeight(0);
  158.     
  159.     SetPort(savePort);
  160. }
  161.  
  162. static void ShowMenuBar(GrafPtr grafPort)
  163. {
  164.     GrafPtr savePort;
  165.     RgnHandle junkRgn;
  166.  
  167.     GetPort(&savePort);
  168.     SetPort(grafPort);
  169.  
  170.         // fill the rounded corners of the screen with black again
  171.     junkRgn = NewRgn();
  172.     CopyRgn(gOldVisRgn, junkRgn);
  173.     DiffRgn(grafPort->visRgn, junkRgn, junkRgn);
  174.  
  175.     #ifdef dangerousPattern
  176.     FillRgn(junkRgn, qd.black);
  177.     #else
  178.     FillRgn(junkRgn, &qd.black);
  179.     #endif
  180.  
  181.     DisposeRgn(junkRgn);
  182.  
  183.         // restore the old vis region
  184.     CopyRgn(gOldVisRgn, grafPort->visRgn);
  185.     DisposeRgn(gOldVisRgn);
  186.     gOldVisRgn = NULL;
  187.     
  188.     LMSetMBarHeight(gOldMBarHeight);
  189.     
  190.     DrawMenuBar();
  191. }
  192.  
  193. int graphics_init()
  194. {
  195.     int i;
  196.     char p1;
  197.     long tmp;
  198.     long memtop=0;
  199.     Rect    windowRectangle,osRect={0,0,600,800};
  200.     char *dst;
  201.     CGrafPtr oldPort;
  202.     GDHandle oldDevice;
  203.     
  204.     my_use_gfxlib=use_gfxlib;
  205.     my_automount_uaedev=automount_uaedev;
  206.     my_screen_res=screen_res;
  207.     my_use_quickdraw=use_quickdraw;
  208.     
  209.     if (CheckForSetup()) ExitToShell();
  210.     
  211.     gfxvidinfo.maxblocklines=600; // Whatever...
  212.     
  213.     if (gfxvidinfo.pixbytes == 1)
  214.     {    myCTAB=GetCTable(128);
  215.         mypal=NewPalette(256, myCTAB, pmTolerant + pmExplicit, 0x0000);
  216.     }
  217.     
  218.     windowRectangle.left=0;
  219.     if (screen_res > 4 || screen_res < 0) screen_res=3;
  220.     if (screen_res == 4 || screen_res == 2) dont_want_aspect = 0;
  221.     else dont_want_aspect = 1;
  222.     switch (screen_res)
  223.     {    case 0:
  224.         case 1:
  225.         case 2:
  226.             CenterScreen=(36*gfxvidinfo.pixbytes)/2;
  227.             windowRectangle.right=320;
  228.             use_lores = 1;
  229.             windowRectangle.top=40;
  230.             if (screen_res == 0) windowRectangle.bottom=200+windowRectangle.top+38;
  231.             else if (screen_res == 1) windowRectangle.bottom=256+windowRectangle.top+38;
  232.                  else windowRectangle.bottom=400+windowRectangle.top+38;
  233.         break;
  234.     
  235.         case 3:
  236.         case 4:
  237.             CenterScreen=36*gfxvidinfo.pixbytes;
  238.             use_lores = 0;
  239.             windowRectangle.right=640;
  240.             if (dont_want_aspect == 0)
  241.             {    windowRectangle.top=0;
  242.                 windowRectangle.bottom=480;
  243.             }
  244.             else
  245.             {    windowRectangle.top=40;
  246.                 windowRectangle.bottom=256+windowRectangle.top+38;
  247.             }
  248.         break;
  249.     }
  250.     
  251.     screenV=windowRectangle.bottom-windowRectangle.top;
  252.     if (dont_want_aspect == 1 || screen_res == 2) screenV -= 12;
  253.     screenH=windowRectangle.right-windowRectangle.left;
  254.     
  255.     mywin = NewCWindow(nil, &windowRectangle, "\pThe Un*x Amiga Emulator", 1, 4, (WindowPtr)-1L, 0, 0);
  256.     SetPort(mywin);
  257.     
  258.     gui_prepare_leds(screenV);
  259.     
  260.     init_colors();
  261.     
  262.     if (use_quickdraw)
  263.     {    GetGWorld(&oldPort, &oldDevice);
  264.         NewGWorld( &gOffscreenBuffer, (gfxvidinfo.pixbytes*8), &osRect, 0L, oldDevice, 0);
  265.         SetGWorld(oldPort, oldDevice);
  266.         gOffscreenPixels = GetGWorldPixMap( gOffscreenBuffer );
  267.         LockPixels(gOffscreenPixels);
  268.         gDrawRect.top=(mywin->portRect).top;
  269.         gDrawRect.left=(mywin->portRect).left;
  270.         gDrawRect.right=(mywin->portRect).right;
  271.         gDrawRect.bottom=(mywin->portRect).bottom;
  272.         gDrawRect.bottom -= 12;
  273.         gOffscreenRect.top=(mywin->portRect).top;
  274.         gOffscreenRect.left=(mywin->portRect).left;
  275.         gOffscreenRect.right=(mywin->portRect).right;
  276.         gOffscreenRect.bottom=(mywin->portRect).bottom;
  277.         gOffscreenRect.bottom -= 12;
  278.         OffsetRect(&gOffscreenRect,(use_lores == 1) ? qd_CenterScreen/2 : qd_CenterScreen,0);
  279.         gOffscreenBaseAddr = (unsigned char *)GetPixBaseAddr(gOffscreenPixels);
  280.         gOffscreenRowBytes = (*gOffscreenPixels)->rowBytes & 0x3fff;
  281.         gfxvidinfo.bufmem=(char *)gOffscreenBaseAddr;
  282.         gfxvidinfo.rowbytes=gOffscreenRowBytes;
  283.         SetGWorld(gOffscreenBuffer, NULL);
  284.         PaintRect(&gOffscreenRect);
  285.         SetGWorld(oldPort, oldDevice);
  286.     }
  287.     else
  288.     {    gfxvidinfo.bufmem=NewPtrClear(600*(800*gfxvidinfo.pixbytes));
  289.         if (gfxvidinfo.bufmem == 0) SysBeep(0);
  290.         gfxvidinfo.rowbytes=800*gfxvidinfo.pixbytes;
  291.     }
  292.     
  293.     if (dont_want_aspect || screen_res == 2) printStatusLine();
  294.     
  295.     if (gfxvidinfo.pixbytes == 1)
  296.     {    SetPalette((WindowPtr) -1L, mypal, false);
  297.     }
  298.     
  299.     buttonstate[0] = buttonstate[1] = buttonstate[2] = 0;
  300.     for(i=0; i<256; i++) keystate[i] = 0;
  301.     
  302.     lastmx = lastmy = 0; newmousecounters=0;
  303.     
  304.     refresh=TickCount();
  305.     
  306. //    tmp=ProfilerInit(collectDetailed,bestTimeBase,200,10);
  307.     return 1;
  308. }
  309.  
  310. void graphics_leave()
  311. {
  312. //    ProfilerDump((unsigned char *)"\pmyProf");
  313. //    ProfilerTerm();
  314.  
  315.     ShowCursor();
  316.     if (dont_want_aspect == 0) if (!mBarState) ShowMenuBar(mywin);
  317.     if (oldDepth != 0) SetDepth(curDevice,oldDepth,0,0);
  318.     FlushEvents (everyEvent,0);
  319.     SndDisposeChannel(newChannel,true);
  320.     if (gfxvidinfo.pixbytes == 1)
  321.     {    DisposePalette(mypal);
  322.         DisposeCTable(myCTAB);
  323.     }
  324.     DisposeWindow(mywin);
  325.     if (use_quickdraw)
  326.     {    DisposeGWorld(gOffscreenBuffer);
  327.     }
  328.     else DisposePtr((Ptr)(gfxvidinfo.bufmem));
  329. }
  330.  
  331. static int next_line_double;
  332. static int next_line_pos = 0;
  333.  
  334. void flush_screen ()
  335. {    short    y,x,y1=0;
  336.     unsigned char *winbaseaddr;
  337.     long *src,*dest;
  338.     unsigned long winrowbytes;
  339.     PixMapHandle    ph;
  340.     CGrafPtr    oldPort;
  341.     GDHandle oldDevice;
  342.  
  343.     if (TickCount() < refresh + 4) return;
  344.     if (!redraw) return;
  345.     if (FrontWindow() != mywin) return;
  346.     if (inhibit_frame) return;
  347.        
  348.        GetGWorld(&oldPort,&oldDevice);
  349.     SetGWorld((CWindowPtr) mywin, oldDevice);
  350.     if (use_quickdraw)
  351.     {    ForeColor(blackColor);    /* Prevents colorizing mode */
  352.         BackColor(whiteColor);    /* Prevents colorizing mode */
  353.         (*((*gOffscreenPixels)->pmTable))->ctSeed = (*((*((*(GetGDevice()))->gdPMap))->pmTable))->ctSeed;
  354.         CopyBits((BitMap *)(*gOffscreenPixels), &(mywin->portBits), &gOffscreenRect, &gDrawRect, srcCopy, (RgnHandle) 0L);
  355.     }
  356.     else
  357.     {    ph=GetGWorldPixMap((CGrafPort *) mywin);
  358.         winbaseaddr=( unsigned char *) GetPixBaseAddr(ph);
  359.         winrowbytes=(*ph)->rowBytes & 0x3FFF;
  360.         winbaseaddr-=((**ph).bounds.left);
  361.         winbaseaddr-=(((**ph).bounds.top)*winrowbytes);
  362.         dest=(long *)winbaseaddr;
  363.         src=(long *)(gfxvidinfo.bufmem)+CenterScreen;
  364.         
  365.         y=0;
  366.         if ((dont_want_aspect == 0 && mBarState == true && y < 20)) y=20;
  367.         dest=(long *)(winbaseaddr+(y*winrowbytes));
  368.         src=(long *)(gfxvidinfo.bufmem+(y*gfxvidinfo.rowbytes))+CenterScreen;
  369.         for (; y< screenV; y++)
  370.         {    for (x=0;x < ((screenH*gfxvidinfo.pixbytes)/sizeof(long));x++) *dest++ = *src++;
  371.         dest=(long *)(winbaseaddr+(y*winrowbytes));
  372.         src=(long *)(gfxvidinfo.bufmem+(y*gfxvidinfo.rowbytes))+CenterScreen;
  373.         }
  374.     }
  375.     SetGWorld(oldPort, oldDevice);
  376. }
  377.  
  378. void flush_block (int start_y, int end_y)
  379. {    short    y,x,y1=0;
  380.     unsigned char *winbaseaddr;
  381.     long *src,*dest;
  382.     unsigned long winrowbytes;
  383.     PixMapHandle    ph;
  384.     Rect            srcRect,dstRect;
  385.     CGrafPtr    oldPort;
  386.     GDHandle oldDevice;
  387.  
  388.     if (TickCount() < refresh + 4) return;
  389.     if (!redraw) return;
  390.     if (FrontWindow() != mywin) return;
  391.     if (inhibit_frame) return;
  392.        
  393.        if (end_y > screenV) end_y=screenV;
  394.        GetGWorld(&oldPort,&oldDevice);
  395.     SetGWorld((CWindowPtr) mywin, oldDevice);
  396.     if (use_quickdraw)
  397.     {    
  398.         srcRect.top=start_y;
  399.         srcRect.bottom=end_y;
  400.         srcRect.left=gOffscreenRect.left;
  401.         srcRect.right=gOffscreenRect.right;
  402.         dstRect.top=start_y;
  403.         dstRect.bottom=end_y;
  404.         dstRect.left=gDrawRect.left;
  405.         dstRect.right=gDrawRect.right;
  406.         
  407.         /* Taken from my favorite book:
  408.            "It is significant, if not surprising, that the Mac and PC cannot come
  409.            to an agreement over the most fundamental issue in the universe: the
  410.            distinction between black and white. On the PC, the pixel value 0
  411.            indicates a pixel of zero intensity, or black. On the Mac, 0 indicates
  412.            a page wich has not been written on, wich leaves it white."
  413.            
  414.                                                    Eric Johnston.
  415.                                        Tricks of the Mac Game Programming Gurus.
  416.         
  417.         Check set_palette and line_to_scr8() on how i fixed that.
  418.         If you know a better way let me know.
  419.         */
  420.         
  421.         ForeColor(blackColor);    /* Prevents colorizing mode */
  422.         BackColor(whiteColor);    /* Prevents colorizing mode */
  423.         (*((*gOffscreenPixels)->pmTable))->ctSeed = (*((*((*(GetGDevice()))->gdPMap))->pmTable))->ctSeed;
  424.         CopyBits((BitMap *)(*gOffscreenPixels), &(mywin->portBits), &srcRect, &dstRect, srcCopy, (RgnHandle) 0L);
  425.     }
  426.     else
  427.     {    ph=GetGWorldPixMap((CGrafPort *) mywin);
  428.         winbaseaddr=( unsigned char *) GetPixBaseAddr(ph);
  429.         winrowbytes=(*ph)->rowBytes & 0x3FFF;
  430.         winbaseaddr-=((**ph).bounds.left);
  431.         winbaseaddr-=(((**ph).bounds.top)*winrowbytes);
  432.         dest=(long *)winbaseaddr;
  433.         src=(long *)(gfxvidinfo.bufmem)+CenterScreen;
  434.         
  435.         y=start_y;
  436.         if ((dont_want_aspect == 0 && mBarState == true && y < 20)) y=20;
  437.         dest=(long *)(winbaseaddr+(y*winrowbytes));
  438.         src=(long *)(gfxvidinfo.bufmem+(y*gfxvidinfo.rowbytes))+CenterScreen;
  439.         for (; y <= end_y; y++)
  440.         {    for (x=0;x < ((screenH*gfxvidinfo.pixbytes)/sizeof(long));x++) *dest++ = *src++;
  441.         dest=(long *)(winbaseaddr+(y*winrowbytes));
  442.         src=(long *)(gfxvidinfo.bufmem+(y*gfxvidinfo.rowbytes))+CenterScreen;
  443.         }
  444.     }
  445.     SetGWorld(oldPort, oldDevice);
  446. }
  447.  
  448. void flush_line(int line_num)
  449. {
  450.     long i;
  451.     char *dst,*src;
  452.     CGrafPtr oldPort;
  453.     GDHandle oldDevice;
  454.      
  455.     if (use_quickdraw)
  456.     {    GetGWorld(&oldPort, &oldDevice);
  457.         SetGWorld(gOffscreenBuffer, NULL);
  458.         dst=(char *)gOffscreenBaseAddr;
  459.         dst+=(char *)((line_num)*gOffscreenRowBytes);
  460.         src=(char *)xlinebuffer;
  461.         BlockMove(src,dst,gOffscreenRowBytes);
  462.         if (next_line_double)
  463.         {    dst=(char *)gOffscreenBaseAddr;
  464.             dst+=(char *)((line_num+1)*gOffscreenRowBytes);
  465.             src=(char *)xlinebuffer;
  466.             BlockMove(src,dst,gOffscreenRowBytes);
  467.         }
  468.         SetGWorld(oldPort, oldDevice);
  469.     }
  470.     else
  471.     {    if (line_num < 481)
  472.         {    dst=(char *)gfxvidinfo.bufmem+((line_num)*gfxvidinfo.rowbytes);
  473.             src=(char *)xlinebuffer;
  474.             BlockMove(src,dst,gfxvidinfo.rowbytes);
  475.         }
  476.         if (next_line_double)
  477.         {    
  478.             if (line_num < 481)
  479.             {   dst=(char *)gfxvidinfo.bufmem+((line_num+1)*gfxvidinfo.rowbytes);
  480.                 src=(char *)xlinebuffer;
  481.             BlockMove(src,dst,gfxvidinfo.rowbytes);
  482.             }
  483.         }
  484.     }
  485. }
  486.  
  487. /* Decode KeySyms. This function knows about all keys that are common 
  488.  * between different keyboard languages.
  489.  */
  490. static int kc_decode (long ks)
  491. {    
  492.     switch (ks)
  493.     {
  494.      case kAKeyMap: return AK_A;
  495.      case kBKeyMap: return AK_B;
  496.      case kCKeyMap: return AK_C;
  497.      case kDKeyMap: return AK_D;
  498.      case kEKeyMap: return AK_E;
  499.      case kFKeyMap: return AK_F;
  500.      case kGKeyMap: return AK_G;
  501.      case kHKeyMap: return AK_H;
  502.      case kIKeyMap: return AK_I;
  503.      case kJKeyMap: return AK_J;
  504.      case kKKeyMap: return AK_K;
  505.      case kLKeyMap: return AK_L;
  506.      case kMKeyMap: return AK_M;
  507.      case kNKeyMap: return AK_N;
  508.      case kOKeyMap: return AK_O;
  509.      case kPKeyMap: return AK_P;
  510.      case kQKeyMap: return AK_Q;
  511.      case kRKeyMap: return AK_R;
  512.      case kSKeyMap: return AK_S;
  513.      case kTKeyMap: return AK_T;
  514.      case kUKeyMap: return AK_U;
  515.      case kVKeyMap: return AK_V;
  516.      case kWKeyMap: return AK_W;
  517.      case kXKeyMap: return AK_X;
  518.      
  519.      case k0KeyMap: return AK_0;
  520.      case k1KeyMap: return AK_1;
  521.      case k2KeyMap: return AK_2;
  522.      case k3KeyMap: return AK_3;
  523.      case k4KeyMap: return AK_4;
  524.      case k5KeyMap: return AK_5;
  525.      case k6KeyMap: return AK_6;
  526.      case k7KeyMap: return AK_7;
  527.      case k8KeyMap: return AK_8;
  528.      case k9KeyMap: return AK_9;
  529.      
  530.      case kKP0KeyMap: return AK_NP0;
  531.      case kKP1KeyMap: return AK_NP1;
  532.      case kKP2KeyMap: return AK_NP2;
  533.      case kKP3KeyMap: return AK_NP3;
  534.      case kKP4KeyMap: return AK_NP4;
  535.      case kKP5KeyMap: return AK_NP5;
  536.      case kKP6KeyMap: return AK_NP6;
  537.      case kKP7KeyMap: return AK_NP7;
  538.      case kKP8KeyMap: return AK_NP8;
  539.      case kKP9KeyMap: return AK_NP9;
  540.     
  541.      case kF1KeyMap: return AK_F1;
  542.      case kF2KeyMap: return AK_F2;
  543.      case kF3KeyMap: return AK_F3;
  544.      case kF4KeyMap: return AK_F4;
  545.      case kF5KeyMap: return AK_F5;
  546.      case kF6KeyMap: return AK_F6;
  547.      case kF7KeyMap: return AK_F7;
  548.      case kF8KeyMap: return AK_F8;
  549.      case kF9KeyMap: return AK_F9;
  550.      case kF10KeyMap: return AK_F10;
  551.     
  552.      case kBackSpaceKeyMap: return AK_BS;
  553.      case kTabKeyMap: return AK_TAB;
  554.      case kReturnKeyMap: return AK_RET;
  555.      case kEscapeKeyMap: return AK_ESC;
  556.      
  557.      case kSpaceBarMap:  return AK_SPC;
  558.      
  559.      case kUpArrowKeyMap: return AK_UP;
  560.      case kDownArrowKeyMap: return AK_DN;
  561.      case kLeftArrowKeyMap: return AK_LF;
  562.      case kRightArrowKeyMap: return AK_RT;
  563.     
  564.      case kF11KeyMap: return AK_inhibit;
  565.  
  566.      case kF12KeyMap: return AK_mousestuff;
  567.  
  568.      case kPgUpKeyMap: return AK_RAMI;
  569.      case kPgDnKeyMap: return AK_LAMI;
  570.      case kBackSlash: return AK_BACKSLASH;
  571.     }
  572.     return -1;
  573. }
  574.  
  575. static int decode_us(long ks)
  576. {
  577.     switch(ks) {
  578.     /* US specific */
  579.  
  580.      case kYKeyMap: return AK_Y;
  581.      case kZKeyMap: return AK_Z;
  582.      case kLBracketKeyMap: return AK_LBRACKET;
  583.      case kRBracketKeyMap: return AK_RBRACKET;
  584.      case kCommaKeyMap: return AK_COMMA;
  585.      case kPeriodKeyMap: return AK_PERIOD;
  586.      case kSlashKeyMap: return AK_SLASH;
  587.      case kSemiColonKeyMap: return AK_SEMICOLON;
  588.      case kMinusKeyMap: return AK_MINUS;
  589.      case kEqualKeyMap: return AK_EQUAL;
  590.      case kQuoteKeyMap: return AK_QUOTE;
  591.     }
  592.  
  593.     return -1;
  594. }
  595.  
  596. static int decode_de(long ks)
  597. {
  598.     switch(ks) {
  599. /* DE specific
  600.      case XK_Y: case XK_y: return AK_Z;
  601.      case XK_Z: case XK_z: return AK_Y;
  602.      case XK_Odiaeresis: case XK_odiaeresis: return AK_SEMICOLON;
  603.      case XK_Adiaeresis: case XK_adiaeresis: return AK_QUOTE;
  604.      case XK_Udiaeresis: case XK_udiaeresis: return AK_LBRACKET;
  605.      case XK_plus: case XK_asterisk: return AK_RBRACKET;
  606.      case XK_comma: return AK_COMMA;
  607.      case XK_period: return AK_PERIOD;
  608.      case XK_less: case XK_greater: return AK_LTGT;
  609.      case XK_numbersign: return AK_NUMBERSIGN;
  610.      case XK_ssharp: return AK_MINUS;
  611.      case XK_apostrophe: return AK_EQUAL;
  612.      case XK_asciicircum: return AK_00;
  613.      case XK_minus: return AK_SLASH;        
  614. */
  615.     }
  616.  
  617.     return -1;
  618. }
  619.  
  620. static int keycode2amiga(long code)
  621. {
  622.     long ks;
  623.     int as;
  624.     
  625.     ks = (code & keyCodeMask) >> 8;
  626.     as = kc_decode (ks);
  627.     
  628.     if (as == -1) {        
  629.     switch(keyboard_lang) {
  630.      case KBD_LANG_US:
  631.         as = decode_us(ks);
  632.         break;
  633.         
  634.      case KBD_LANG_DE:
  635.         as = decode_de(ks);
  636.         break;
  637.         
  638.      default:
  639.         as = -1;
  640.         break;
  641.     }
  642.     }
  643.     if(-1 != as)
  644.     return as;
  645.     return -1;
  646. }
  647.  
  648. void handle_events()
  649. {    WindowPeek    wp;
  650.     short        windowPart;
  651.     Boolean repeat;
  652.     Boolean itHappened;
  653.     Point   mpos;
  654.     EventRecord event;
  655.     int kc,i,count;
  656.     char    osKind;
  657.     GrafPtr    oldSave;
  658.     
  659.     GetPort(&oldSave);
  660.     if ((redraw) && mywin != FrontWindow()) SelectWindow(mywin);
  661.     
  662.     SetEventMask(-1);
  663.     
  664.     if (diskInit)
  665.     {    macDiskStatus[0]=!disk_empty(0);
  666.         SetMenuItemText(GetMenuHandle(kDrivesMenuID), 1, macDiskStatus[0] ? "\pEject Disk in DF0:" : "\pInsert Disk in DF0:");
  667.         macDiskStatus[1]=!disk_empty(1);
  668.         SetMenuItemText(GetMenuHandle(kDrivesMenuID), 2, macDiskStatus[1] ? "\pEject Disk in DF1:" : "\pInsert Disk in DF1:");
  669.         macDiskStatus[2]=!disk_empty(2);
  670.         SetMenuItemText(GetMenuHandle(kDrivesMenuID), 3, macDiskStatus[2] ? "\pEject Disk in DF2:" : "\pInsert Disk in DF2:");
  671.         macDiskStatus[3]=!disk_empty(3);
  672.         SetMenuItemText(GetMenuHandle(kDrivesMenuID), 4, macDiskStatus[3] ? "\pEject Disk in DF3:" : "\pInsert Disk in DF3:");
  673.         diskInit=false;
  674.     }
  675.     
  676.     if (redraw)
  677.     {    gui_update_leds();
  678.         macHandleCursors();
  679.     }
  680.     
  681.     GetKeys(keys);
  682.     if (BitTst(&keys, kCommandRawKey))
  683.     buttonstate[2] = 1;
  684.     else
  685.     buttonstate[2] = 0;
  686.     
  687.     if (BitTst(&keys, kShiftRawKey))
  688.     {    
  689.     if (!keystate[AK_LSH]) {
  690.         keystate[AK_LSH] = 1;
  691.         record_key (AK_LSH << 1);
  692.         goto label1;
  693.     }
  694.     } else {
  695.     if (keystate[AK_LSH]) {
  696.         keystate[AK_LSH] = 0;
  697.         record_key ((AK_LSH << 1) | 1);
  698.         goto label1;
  699.     }
  700.     }
  701.     if (BitTst(&keys, kControlRawKey))
  702.     {    
  703.     if (!keystate[AK_CTRL]) {
  704.         keystate[AK_CTRL] = 1;
  705.         record_key (AK_CTRL << 1);
  706.         goto label1;
  707.     }
  708.     } else {    
  709.     if (keystate[AK_CTRL]) {
  710.         keystate[AK_CTRL] = 0;
  711.         record_key ((AK_CTRL << 1) | 1);
  712.         goto label1;
  713.     }
  714.     }
  715.     if (BitTst(&keys, kCapsRawKey))
  716.     {    
  717.     if (!keystate[AK_CAPSLOCK]) {
  718.         keystate[AK_CAPSLOCK] = 1;
  719.         record_key (AK_CAPSLOCK << 1);
  720.         goto label1;
  721.     }
  722.     } else {
  723.     if (keystate[AK_CAPSLOCK]) {
  724.         keystate[AK_CAPSLOCK] = 0;
  725.         record_key ((AK_CAPSLOCK << 1) | 1);
  726.         goto label1;
  727.     }
  728.     }
  729.     if (BitTst(&keys, kOptionRawKey))
  730.     {    
  731.     if (!keystate[AK_LALT]) {
  732.         keystate[AK_LALT] = 1;
  733.         record_key (AK_LALT << 1);
  734.         goto label1;
  735.     }
  736.     } else {
  737.     if (keystate[AK_LALT]) {
  738.         keystate[AK_LALT] = 0;
  739.         record_key ((AK_LALT << 1) | 1);
  740.         goto label1;
  741.     }
  742.     }
  743.     do {
  744.     repeat = 0;
  745.     newmousecounters=0;
  746.     itHappened=WaitNextEvent(-1,&event,0L,(*mywin).visRgn);
  747.  
  748.     switch(event.what) {
  749.      case keyDown:
  750.      case autoKey: {
  751.           if ((event.modifiers & cmdKey) != 0)
  752.           {    HandleMenu(MenuKey((char) (event.message & charCodeMask)));
  753.           }
  754.           else
  755.           {    int kc = keycode2amiga(event.message);
  756.              if (kc == -1) break;
  757.              switch (kc)
  758.              {    case AK_mousestuff:
  759.                      togglemouse();
  760.                       break;
  761.         
  762.                 case AK_inhibit:
  763.                       inhibit_frame ^= 1;
  764.                       break;
  765.         
  766.                 default:
  767.                       if (!keystate[kc])
  768.                       {     keystate[kc] = 1;
  769.                          record_key (kc << 1);
  770.                       }
  771.                       break;
  772.              }
  773.         }
  774.          break;
  775.      }
  776.      case keyUp: {
  777.          kc = keycode2amiga(event.message);
  778.          if (kc == -1) break;
  779.          keystate[kc] = 0;
  780.          record_key ((kc << 1) | 1);
  781.          break;
  782.      }
  783.      case mouseDown:
  784.          windowPart = FindWindow (event.where, (WindowPtr*) &wp);
  785.          if (windowPart == inMenuBar) HandleMenu(MenuSelect(event.where));
  786.          else
  787.          if (windowPart == inSysWindow) SystemClick (&event, (WindowPtr) wp);
  788.         else buttonstate[0] = 1;
  789.         break;
  790.          
  791.      case osEvt:
  792.          osKind=(event.message) >> 24;
  793.          if (osKind == suspendResumeMessage)
  794.          {    osKind=(event.message)&1;
  795.              if (osKind)
  796.              {    redraw=true; // Resume
  797.                  flush_screen();
  798.                  if (dont_want_aspect || screen_res == 2)
  799.                 {    SelectWindow(mywin);
  800.                     printStatusLine();
  801.                 }
  802.             }
  803.              else redraw=false; // Suspend
  804.          }
  805.          break;
  806.      case mouseUp:
  807.         buttonstate[0] = 0;
  808.         buttonstate[2] = 0;
  809.         break;
  810.     }
  811.     if (redraw)
  812.     {    GetMouse(&mpos);
  813.         if (mpos.h != lastmx) { lastmx=mpos.h; /* repeat = 1;*/ }
  814.         if (mpos.v != lastmy) { lastmy=mpos.v; /*repeat = 1;*/ }
  815.     }
  816.     } while (repeat);
  817.     
  818. label1:
  819.     /* "Affengriff" */
  820.     if(keystate[AK_CTRL] && keystate[AK_LAMI] && keystate[AK_RAMI])
  821.         MC68000_reset();
  822.     SetPort(oldSave);
  823. }
  824.  
  825. int debuggable()
  826. {
  827.     return 1;
  828. }
  829.  
  830. int needmousehack()
  831. {
  832.     return 1;
  833. }
  834.  
  835. void LED(int on)
  836. {
  837. }
  838.  
  839. void parse_cmdline ()
  840. {
  841.     /* No commandline on the Mac. */
  842. }
  843.  
  844. static void PStrCat ( StringPtr p1, StringPtr p2)
  845. {
  846.     register int len;
  847.     register int total;
  848.     StringPtr    p3;
  849.     
  850.     len = *p1++;
  851.     total = len +*p2;
  852.     
  853.     p3=p2;
  854.     p2=p2+ (*p2 + 1);
  855.     
  856.     while (--len>=0) *p2++=*p1++;
  857.     *p3=total;
  858. }
  859.  
  860. static void PStrCopy ( StringPtr p1, StringPtr p2)
  861. {
  862.     register int len;
  863.     
  864.     len = *p2++ = *p1++;
  865.     while (--len>=0) *p2++=*p1++;
  866. }
  867.  
  868. short vRefNum=0;
  869. long dirID=0;
  870.  
  871. static void HandleMenu (long mSelect)
  872. {    short        menuID;
  873.     short        menuItem;
  874.     Str32        name;
  875.     GrafPtr        savePort;
  876.     WindowPtr    batchWin;
  877.     Str255        batchStr,batchStr2;
  878.     StandardFileReply        inputReply;
  879.     char        strSize,i;
  880.     long        count;
  881.     FILE        *outFile;
  882.     char        fileBuf[512];
  883.     int            backup=0;
  884.  
  885.     menuID = HiWord(mSelect);
  886.     menuItem = LoWord(mSelect);
  887.  
  888.     if (menuID == 0) return;
  889.     switch (menuID)
  890.     {    case kAppleMenuID:
  891.               if (menuItem == 1)
  892.               {    if (!macCursorState) ShowCursor();
  893.                 macCursorState=true;
  894.                   Alert(kAboutDialogID,0); // About Box
  895.                   if (dont_want_aspect || screen_res == 2) printStatusLine();
  896.               }
  897.              else
  898.              {    GetPort(&savePort);
  899.                  GetItem(GetMenuHandle(kAppleMenuID), menuItem, name);
  900.                 OpenDeskAcc(name);
  901.                 SystemTask();
  902.                 SetPort(savePort);
  903.             }
  904.             break;
  905.          
  906.          case kFileMenuID:
  907.             switch (menuItem)
  908.             {    case 1:
  909.                     MC68000_reset();
  910.                 break;
  911.                 
  912.                 case 3:
  913.                     if (dont_want_aspect == 0)
  914.                     {    if (mBarState) HideMenuBar(mywin);
  915.                         else ShowMenuBar(mywin);
  916.                         mBarState=!mBarState;
  917.                     }
  918.                 break;
  919.                 
  920.                 case 5:
  921.                     broken_in = 1;
  922.                     specialflags |= SPCFLAG_BRK;
  923.                 break;
  924.                 
  925.                 case 7:
  926.                     inhibit_frame ^= 1;
  927.                     if (inhibit_frame) SetMenuItemText(GetMenuHandle(kFileMenuID), 7, "\pTurn Screen Update On");
  928.                     else SetMenuItemText(GetMenuHandle(kFileMenuID), 7, "\pTurn Screen Update Off");
  929.                 break;
  930.                 
  931.                 case 9:
  932.                     produce_sound= !produce_sound;
  933.                     if (produce_sound) SetMenuItemText(GetMenuHandle(kFileMenuID), 9, "\pTurn Sound Off");
  934.                     else SetMenuItemText(GetMenuHandle(kFileMenuID), 9, "\pTurn Sound On");
  935.                     WritePrefs(0);
  936.                 break;
  937.                 
  938.                 case 11:
  939.                     fake_joystick= !fake_joystick;
  940.                     if (fake_joystick) SetMenuItemText(GetMenuHandle(kFileMenuID), 11, "\pTurn Joystick Off");
  941.                     else SetMenuItemText(GetMenuHandle(kFileMenuID), 11, "\pTurn Joystick On");
  942.                     WritePrefs(0);
  943.                 break;
  944.                 
  945.                 case 13:
  946.                     broken_in = 1;
  947.                     specialflags |= SPCFLAG_BRK;
  948.                     quit_program=1;
  949.                 break;
  950.             }
  951.             break;
  952.         
  953.         case kDrivesMenuID:
  954.             if (menuItem >= 1 && menuItem <= 4)
  955.             {    if (macDiskStatus[menuItem-1]) disk_eject(menuItem-1);
  956.                     else
  957.                     {    if (!macCursorState) ShowCursor();
  958.                         if (!mBarState) ShowMenuBar(mywin);
  959.                         macCursorState=true;
  960.                         StandardGetFile(nil,-1L,nil,&inputReply);
  961.                         if (inputReply.sfGood)
  962.                         {    vRefNum=inputReply.sfFile.vRefNum;
  963.                             dirID=inputReply.sfFile.parID;
  964.                             disk_insert (menuItem-1, p2cstr(inputReply.sfFile.name));
  965.                         }
  966.                         else macDiskStatus[menuItem-1] = !macDiskStatus[menuItem-1];
  967.                         if (!mBarState) HideMenuBar(mywin);
  968.                     }
  969.                     macDiskStatus[menuItem-1] = !macDiskStatus[menuItem-1];
  970.                     if (macDiskStatus[menuItem-1]) PStrCopy("\pEject Disk in DF",batchStr);
  971.                     else PStrCopy("\pInsert Disk in DF",batchStr);
  972.                     NumToString((long)(menuItem-1),batchStr2);
  973.                     PStrCat(batchStr2,batchStr);
  974.                     PStrCat("\p:",batchStr);
  975.                     SetMenuItemText(GetMenuHandle(kDrivesMenuID), menuItem, batchStr);
  976.         
  977.             }
  978.             if (menuItem == 6)
  979.             {    if (!macCursorState) ShowCursor();
  980.                 macCursorState=true;
  981.                 for (count=0;count<512;count++) fileBuf[count]=0;
  982.                 errno=0;
  983.                 outFile=fopen("hardfile","wb");
  984.                 if (outFile != 0)
  985.                 {    for (count=0;count<16384;count++)
  986.                     {    fwrite(fileBuf, sizeof(char), 512, outFile);
  987.                         if (errno != 0)
  988.                         {    ParamAString("\pError generating the hardfile!.\n Make sure you have at least 8Mb of free storage on your Harddrive.");
  989.                             DisplayError(kQuitError);
  990.                         }
  991.                     }
  992.                     fclose(outFile);
  993.                     Alert(kHardfileDialogID,0);
  994.                 }
  995.                 else
  996.                 {    ParamAString("\pCan't create the hardfile!.\n Make sure your Harddrive isnt either software or hardware locked.");
  997.                     DisplayError(kQuitError);
  998.                 }
  999.             }
  1000.             if (menuItem == 7)
  1001.             {    my_automount_uaedev=!my_automount_uaedev;
  1002.                 WritePrefs(0);
  1003.                 ParamAString("\pChanges will take effect the next time you run UAE.");
  1004.                 DisplayError(kQuitError);
  1005.                 CheckItem(GetMenuHandle(kDrivesMenuID),7,my_automount_uaedev ? false : true);
  1006.             }
  1007.             if (menuItem == 9)
  1008.             {    if (!macCursorState) ShowCursor();
  1009.                 macCursorState=true;
  1010.                 Share_main();
  1011.             }
  1012.         break;
  1013.         
  1014.         case kMemoryMenuID:
  1015.             if (menuItem == 1) use_slow_mem = !use_slow_mem;
  1016.             WritePrefs(0);
  1017.             ParamAString("\pChanges will take effect the next time you run UAE.");
  1018.             DisplayError(kQuitError);
  1019.             if (use_slow_mem) SetMenuItemText(GetMenuHandle(kMemoryMenuID), 1, "\pDisable 1 Mb (SlowMem)");
  1020.             else SetMenuItemText(GetMenuHandle(kMemoryMenuID), 1, "\pEnable 1 Mb (SlowMem)");
  1021.         break;
  1022.             
  1023.         case kResMenuID:
  1024.             my_screen_res=(int)menuItem-1;
  1025.             WritePrefs(0);
  1026.             CheckItem(GetMenuHandle(kResMenuID),screen_res+1,false);
  1027.             CheckItem(GetMenuHandle(kResMenuID),my_screen_res+1,true);
  1028.             ParamAString("\pChanges will take effect the next time you run UAE.");
  1029.             DisplayError(kQuitError);
  1030.         break;
  1031.         
  1032.         case kRateMenuID:
  1033.             for (count=1;count<5;count++) CheckItem(GetMenuHandle(kRateMenuID),count,false);
  1034.             if (menuItem == 1) framerate=1;
  1035.             if (menuItem == 2) framerate=3;
  1036.             if (menuItem == 3) framerate=5;
  1037.             if (menuItem == 4) framerate=7;
  1038.             CheckItem(GetMenuHandle(kRateMenuID),menuItem,true);
  1039.             WritePrefs(0);
  1040.         break;
  1041.         
  1042.         case kVideoMenuID:
  1043.         if (menuItem == 5)
  1044.         {    my_use_quickdraw = !my_use_quickdraw;
  1045.             WritePrefs(0);
  1046.             CheckItem(GetMenuHandle(kVideoMenuID),5,my_use_quickdraw ? true : false);
  1047.             ParamAString("\pChanges will take effect the next time you run UAE.");
  1048.             DisplayError(kQuitError);
  1049.         }
  1050.         if (menuItem == 7)
  1051.         {    my_use_gfxlib = !my_use_gfxlib;
  1052.             WritePrefs(0);
  1053.             CheckItem(GetMenuHandle(kVideoMenuID),7,my_use_gfxlib ? true : false);
  1054.             ParamAString("\pChanges will take effect the next time you run UAE.");
  1055.             DisplayError(kQuitError);
  1056.         }
  1057.         break;
  1058.         
  1059.         default:
  1060.             break;
  1061.     }
  1062.     HiliteMenu(0);
  1063.     flush_screen();
  1064.     if (dont_want_aspect  || screen_res == 2) printStatusLine();
  1065. }
  1066.  
  1067. static void macHandleCursors(void)
  1068. {    Point    mpos;
  1069.  
  1070.     if (redraw)
  1071.     {    GetMouse(&mpos);
  1072.         if (!dont_want_aspect && mBarState && screen_res == 4)
  1073.         {    if (mpos.v < 20)
  1074.             {    ShowCursor();
  1075.                 macCursorState=true;
  1076.             }
  1077.             else
  1078.             {    if (macCursorState)
  1079.                 {    HideCursor();
  1080.                     macCursorState=false;
  1081.                 }
  1082.             }
  1083.         }
  1084.         else
  1085.         if (PtInRect(mpos,&(mywin->portRect)))
  1086.         {    if (macCursorState)
  1087.             {    HideCursor();
  1088.                 macCursorState=false;
  1089.             }
  1090.         }
  1091.         else
  1092.         {    if (!macCursorState)
  1093.             {    ShowCursor();
  1094.                 macCursorState=true;
  1095.             }
  1096.         }
  1097.     }
  1098. }
  1099.  
  1100. // Check Minimal System Configuration and Setup
  1101. static Boolean CheckForSetup (void)
  1102. {    Boolean            retvalue=false;
  1103.     SysEnvRec        env;
  1104.     
  1105.     oldDepth=0;
  1106.     SysEnvirons( 2, &env );
  1107.     
  1108.     if ( env.systemVersion < 0x0700 )
  1109.     {    ParamAString("\pUAE requires System 7 or later!\n Press Ok to Quit...");
  1110.         DisplayError(kQuitError);
  1111.         retvalue=true;
  1112.     }
  1113.     if ( !env.hasColorQD)
  1114.     {    ParamAString("\pUAE requires Color QuickDraw!\n Press Ok to Quit...");
  1115.         DisplayError(kQuitError);
  1116.         retvalue=true;
  1117.     }
  1118.     curDevice = GetMainDevice();
  1119.     gfxvidinfo.pixbytes=((*(*curDevice)->gdPMap)->pixelSize)/8;
  1120.     return(retvalue);
  1121. }
  1122.  
  1123. // Shows up the standard error alert;
  1124. static int DisplayError(int ID)
  1125. {    int    ret=0;
  1126.  
  1127.     InitCursor();
  1128.     ret=Alert(ID,0);
  1129.  
  1130.     return (ret);
  1131. }
  1132.  
  1133. // Parses a Pascal string for error display
  1134. static void ParamAString( ConstStr255Param theStr )
  1135. {
  1136.     ParamText(theStr, "\p", "\p", "\p");
  1137. }
  1138.  
  1139. static void printStatusLine (void)
  1140. {    GrafPtr savePort;
  1141.     Rect    updateRect;
  1142.  
  1143.     updateRect.top=screenV;
  1144.     updateRect.bottom=screenV+38;
  1145.     updateRect.left=0;
  1146.     updateRect.right=screenH;
  1147.     GetPort(&savePort);
  1148.     SetPort(mywin);
  1149.     EraseRect(&updateRect);
  1150.     MoveTo(10,screenV+10);
  1151.     TextFont(monaco);
  1152.     TextSize(9);
  1153.     if (screen_res >= 3)
  1154.     DrawString("\pPower LED:        Drive LEDs:  DF0:        DF1:        DF2:        DF3:");
  1155.     else DrawString("\pPower:      DF0:      DF1:      DF2:      DF3:");
  1156.     TextFont(0);
  1157.      TextSize(0);
  1158.      SetPort(savePort);
  1159. }
  1160.  
  1161. typedef struct {
  1162.     StandardFileReply *replyPtr;
  1163.     FSSpec oldSelection;
  1164. } SFData, *SFDataPtr;
  1165.  
  1166. /* constants */
  1167.  
  1168. #define    kSelectItem            10
  1169. #define    kSFDlg                128
  1170. #define    kCanSelectDesktop    true
  1171. #define    kSelectStrRsrc        128
  1172. #define kDefaultSelectString "\pSelect"
  1173. #define    kDeskStrRsrc        129
  1174. #define    kDefaultDeskString    "\pDesktop"
  1175. #define    kSelectKey            's'
  1176.  
  1177. /* globals */
  1178.  
  1179. Boolean gHasFindFolder;
  1180. FSSpec gDeskFolderSpec;
  1181. Str255 gSelectString;
  1182. Str255 gDesktopFName;
  1183.  
  1184. FileFilterYDUPP Share_FilterAllFiles_UPP;
  1185. DlgHookYDUPP Share_MyDlgHook_UPP;
  1186. ModalFilterYDUPP Share_MyModalFilter_UPP;
  1187.  
  1188. /* prototypes */
  1189.  
  1190. static void Share_Init(void);
  1191. static Boolean Share_CustomGet(FSSpec *fSpec);
  1192. static pascal short Share_MyDlgHook(short item,DialogPtr theDlg,Ptr userData);
  1193. static pascal Boolean Share_MyModalFilter(DialogPtr theDlg,EventRecord *ev,short *itemHit,Ptr myData);
  1194. static void Share_HitButton(DialogPtr theDlg,short item);
  1195. static pascal Boolean Share_FilterAllFiles(CInfoPBPtr pb, Ptr myDataPtr);
  1196. static void Share_SetSelectButtonName(StringPtr selName,Boolean hilited,DialogPtr theDlg);
  1197. static Boolean Share_SameFile(FSSpec *file1,FSSpec *file2);
  1198. static Boolean Share_GetFSSpecPartialName(FSSpec *file,StringPtr fName);
  1199. static OSErr Share_GetDeskFolderSpec(FSSpec *fSpec,short vRefNum);
  1200. static OSErr Share_MakeCanonFSSpec(FSSpec *fSpec);
  1201. static Boolean Share_ShouldHiliteSelect(FSSpec *fSpec);
  1202.  
  1203.  
  1204. static void Share_main(void)
  1205. {    FSSpec fSpec;
  1206.     Boolean good;
  1207.     GrafPtr oldPort;
  1208.     char share_path[1024];
  1209.     Handle    share_handle;
  1210.     short backup;
  1211.     
  1212.     GetPort(&oldPort);
  1213.     Share_Init();
  1214.     
  1215.     good = Share_CustomGet(&fSpec);
  1216.     
  1217.     if (good)
  1218.     {    Share_ResolvePath(&fSpec,share_path);
  1219.         backup=filesys_vRefNum;
  1220.         filesys_vRefNum=fSpec.vRefNum;
  1221.         WritePrefs(share_path);
  1222.         filesys_vRefNum=backup;
  1223.     }
  1224.     SetPort(oldPort);
  1225. }
  1226.  
  1227. static void Share_Init(void)
  1228. {
  1229.     Handle strHndl;
  1230.     
  1231.     gHasFindFolder = true;
  1232.     
  1233.     Share_FilterAllFiles_UPP=NewFileFilterYDProc(Share_FilterAllFiles);
  1234.     Share_MyDlgHook_UPP=NewDlgHookYDProc(Share_MyDlgHook);
  1235.     Share_MyModalFilter_UPP=NewModalFilterYDProc(Share_MyModalFilter);
  1236.     
  1237.     strHndl = Get1Resource('STR ',kSelectStrRsrc);
  1238.     if (ResError()!=noErr || !strHndl || !*strHndl)
  1239.         BlockMove(kDefaultSelectString,gSelectString,kDefaultSelectString[0]+1);
  1240.     else {
  1241.         BlockMove(*strHndl,&gSelectString,(long)((unsigned char *)(*strHndl)[0]+1));
  1242.         ReleaseResource(strHndl);
  1243.     }
  1244.  
  1245.     strHndl = Get1Resource('STR ',kDeskStrRsrc);
  1246.     if (ResError()!=noErr || !strHndl || !*strHndl)
  1247.         BlockMove(kDefaultDeskString,gDesktopFName,kDefaultSelectString[0]+1);
  1248.     else {
  1249.         BlockMove(*strHndl,&gDesktopFName,(long)((unsigned char *)(*strHndl)[0]+1));
  1250.         ReleaseResource(strHndl);
  1251.     }
  1252. }
  1253.  
  1254.  
  1255. /* do getfile */
  1256.  
  1257. static Boolean Share_CustomGet(FSSpec *fSpec)
  1258. {
  1259.     Point where = {-1,-1};
  1260.     SFReply reply;
  1261.     DialogPtr theDialog;
  1262.     short item;
  1263.     StandardFileReply sfReply;
  1264.     SFData sfUserData;
  1265.     OSErr err;
  1266.     Boolean targetIsFolder,wasAliased;
  1267.     
  1268.     /* initialize user data area */
  1269.     
  1270.     sfUserData.replyPtr = &sfReply;
  1271.     sfUserData.oldSelection.vRefNum = -9999;    /* init to ridiculous value */
  1272.     
  1273.     CustomGetFile(Share_FilterAllFiles_UPP,-1,nil,&sfReply,kSFDlg,where,Share_MyDlgHook_UPP,
  1274.                     Share_MyModalFilter_UPP,nil,nil,&sfUserData);
  1275.     
  1276.     if (sfReply.sfGood) {
  1277.         err = ResolveAliasFile(&sfReply.sfFile,true,&targetIsFolder,&wasAliased);
  1278.         if (err!=noErr)
  1279.             return false;
  1280.     }
  1281.     
  1282.     err = FSMakeFSSpec(sfReply.sfFile.vRefNum,sfReply.sfFile.parID,sfReply.sfFile.name,fSpec);
  1283.     if (err!=noErr)
  1284.         return false;
  1285.     
  1286.     return sfReply.sfGood;
  1287. }
  1288.  
  1289. static pascal short Share_MyDlgHook(short item,DialogPtr theDlg,Ptr userData)
  1290. {
  1291.     SFDataPtr sfUserData;
  1292.     Boolean hiliteButton;
  1293.     FSSpec curSpec;
  1294.     OSType refCon;
  1295.     
  1296.     refCon = GetWRefCon(theDlg);
  1297.     if (refCon!=sfMainDialogRefCon)
  1298.         return item;
  1299.         
  1300.     sfUserData = (SFDataPtr) userData;
  1301.     
  1302.     if (item==sfHookFirstCall || item==sfHookLastCall)
  1303.         return item;
  1304.     
  1305.     if (item==sfItemVolumeUser) {
  1306.         sfUserData->replyPtr->sfFile.name[0] = '\0';
  1307.         sfUserData->replyPtr->sfFile.parID = 2;
  1308.         sfUserData->replyPtr->sfIsFolder = false;
  1309.         sfUserData->replyPtr->sfIsVolume = false;
  1310.         sfUserData->replyPtr->sfFlags = 0;
  1311.         item = sfHookChangeSelection;
  1312.     }
  1313.         
  1314.     if (!Share_SameFile(&sfUserData->replyPtr->sfFile,&sfUserData->oldSelection)) {
  1315.         BlockMove(&sfUserData->replyPtr->sfFile,&curSpec,sizeof(FSSpec));
  1316.         Share_MakeCanonFSSpec(&curSpec);
  1317.         
  1318.         if (curSpec.vRefNum!=sfUserData->oldSelection.vRefNum)
  1319.             Share_GetDeskFolderSpec(&gDeskFolderSpec,curSpec.vRefNum);    
  1320.         Share_SetSelectButtonName(curSpec.name,Share_ShouldHiliteSelect(&curSpec),theDlg);
  1321.         
  1322.         BlockMove(&sfUserData->replyPtr->sfFile,&sfUserData->oldSelection,sizeof(FSSpec));
  1323.     }
  1324.     
  1325.     if (item==kSelectItem)
  1326.         item = sfItemOpenButton;
  1327.         
  1328.     return item;
  1329. }
  1330.  
  1331.  
  1332. static pascal Boolean Share_MyModalFilter(DialogPtr theDlg,EventRecord *ev,short *itemHit,Ptr myData)
  1333. {
  1334.     Boolean evHandled;
  1335.     char keyPressed;
  1336.     OSType refCon;
  1337.     
  1338.     refCon = GetWRefCon(theDlg);
  1339.     if (refCon!=sfMainDialogRefCon)
  1340.         return false;
  1341.         
  1342.     evHandled = false;
  1343.     
  1344.     switch (ev->what) {
  1345.         case keyDown:
  1346.         case autoKey:
  1347.             keyPressed = ev->message & charCodeMask;
  1348.             if ((ev->modifiers & cmdKey) != 0) {
  1349.                 switch (keyPressed) {
  1350.                     case kSelectKey:
  1351.                         Share_HitButton(theDlg,kSelectItem);
  1352.                         *itemHit = kSelectItem;
  1353.                         evHandled = true;
  1354.                         break;
  1355.                 }
  1356.             }
  1357.             break;
  1358.     }
  1359.     
  1360.     return evHandled;
  1361. }
  1362.  
  1363.  
  1364. static void Share_HitButton(DialogPtr theDlg,short item)
  1365. {
  1366.     short iType;
  1367.     Handle iHndl;
  1368.     Rect iRect;
  1369.     long fTicks;
  1370.     
  1371.     GetDItem(theDlg,item,&iType,&iHndl,&iRect);
  1372.     HiliteControl((ControlHandle)iHndl,inButton);
  1373.     Delay(5,&fTicks);
  1374.     HiliteControl((ControlHandle)iHndl,0);
  1375. }
  1376.  
  1377.  
  1378. static pascal Boolean Share_FilterAllFiles(CInfoPBPtr pb, Ptr myDataPtr)
  1379. {
  1380.     if (pb->hFileInfo.ioFlAttrib & (1<<4))    /* file is a directory */
  1381.         return false;
  1382.  
  1383.     return true;
  1384. }
  1385.  
  1386.  
  1387. static void Share_SetSelectButtonName(StringPtr selName,Boolean hilited,DialogPtr theDlg)
  1388. {
  1389.     ControlHandle selectButton;
  1390.     short iType;
  1391.     Handle iHndl;
  1392.     Rect iRect;
  1393.     Str255 storeName,tempLenStr,tempSelName;
  1394.     short btnWidth;
  1395.     
  1396.     BlockMove(selName,tempSelName,selName[0]+1);
  1397.     GetDItem(theDlg,kSelectItem,&iType,&iHndl,&iRect);
  1398.     
  1399.     /* truncate select name to fit in button */
  1400.     
  1401.     btnWidth = iRect.right - iRect.left;
  1402.     BlockMove(gSelectString,tempLenStr,gSelectString[0]+1);
  1403.     p2cstr(tempLenStr);
  1404.     strcat((char *)tempLenStr," ╥╙  ");
  1405.     c2pstr((char *)tempLenStr);
  1406.     btnWidth -= StringWidth(tempLenStr);
  1407.     TruncString(btnWidth,tempSelName,smTruncMiddle);
  1408.     
  1409.     BlockMove(gSelectString,storeName,gSelectString[0]+1);
  1410.     p2cstr(storeName);
  1411.     p2cstr(tempSelName);
  1412.     strcat((char *)storeName," ╥");
  1413.     strcat((char *)storeName,(char *)tempSelName);
  1414.     strcat((char *)storeName,"╙");
  1415.     
  1416.     c2pstr((char *)storeName);
  1417.     c2pstr((char *)tempSelName);
  1418.     SetCTitle((ControlHandle)iHndl,storeName);
  1419.     
  1420.     SetDItem(theDlg,kSelectItem,iType,iHndl,&iRect);
  1421.  
  1422.     if (hilited)
  1423.         HiliteControl((ControlHandle)iHndl,0);
  1424.     else
  1425.         HiliteControl((ControlHandle)iHndl,255);        
  1426. }
  1427.  
  1428.  
  1429. static Boolean Share_SameFile(FSSpec *file1,FSSpec *file2)
  1430. {
  1431.     if (file1->vRefNum != file2->vRefNum)
  1432.         return false;
  1433.     if (file1->parID != file2->parID)
  1434.         return false;
  1435.     if (!EqualString(file1->name,file2->name,false,true))
  1436.         return false;
  1437.     
  1438.     return true;
  1439. }
  1440.  
  1441.  
  1442. static OSErr Share_GetDeskFolderSpec(FSSpec *fSpec,short vRefNum)
  1443. {
  1444.     DirInfo infoPB;
  1445.     OSErr err;
  1446.     
  1447.     if (!gHasFindFolder) {
  1448.         fSpec->vRefNum = -9999;
  1449.         return -1;
  1450.     }
  1451.     
  1452.     fSpec->name[0] = '\0';
  1453.     err = FindFolder(vRefNum,kDesktopFolderType,kDontCreateFolder,
  1454.                         &fSpec->vRefNum,&fSpec->parID);
  1455.     if (err!=noErr)
  1456.         return err;
  1457.     
  1458.     return Share_MakeCanonFSSpec(fSpec);
  1459. }
  1460.  
  1461.  
  1462. static Boolean Share_ShouldHiliteSelect(FSSpec *fSpec)
  1463. {
  1464.     if (Share_SameFile(fSpec,&gDeskFolderSpec)) {
  1465.         BlockMove(gDesktopFName,fSpec->name,gDesktopFName[0]+1);
  1466.         return kCanSelectDesktop;
  1467.     }
  1468.     else
  1469.         return true;
  1470. }
  1471.  
  1472. static OSErr Share_MakeCanonFSSpec(FSSpec *fSpec)
  1473. {
  1474.     CInfoPBRec infoPB;
  1475.     OSErr err;
  1476.  
  1477.     if (fSpec->name[0] != '\0')
  1478.         return;
  1479.         
  1480.     infoPB.dirInfo.ioNamePtr = fSpec->name;
  1481.     infoPB.dirInfo.ioVRefNum = fSpec->vRefNum;
  1482.     infoPB.dirInfo.ioDrDirID = fSpec->parID;
  1483.     infoPB.dirInfo.ioFDirIndex = -1;
  1484.     err = PBGetCatInfo(&infoPB,false);
  1485.     fSpec->parID = infoPB.dirInfo.ioDrParID;
  1486.     
  1487.     return err;
  1488. }
  1489.  
  1490. static void Share_ResolvePath (FSSpec *fSpec, char *path)
  1491. {    char volname[128];
  1492.     char dirname[128];
  1493.     char path_copy[1024];
  1494.     short the_vRefNum;
  1495.     long  the_parID;
  1496.     CInfoPBRec infoPB;
  1497.  
  1498.     volname[0]=0;
  1499.     strcpy(dirname,(char *)fSpec->name);
  1500.     p2cstr((unsigned char *)dirname);
  1501.     
  1502.     strcpy(path,dirname);
  1503.     
  1504.     the_vRefNum=(fSpec->vRefNum);
  1505.     the_parID=(fSpec->parID);
  1506.  
  1507.     infoPB.dirInfo.ioNamePtr = (unsigned char *)volname;
  1508.     infoPB.dirInfo.ioVRefNum = the_vRefNum;
  1509.     infoPB.dirInfo.ioDrDirID = fsRtDirID;
  1510.     infoPB.dirInfo.ioFDirIndex = -1;
  1511.     PBGetCatInfo(&infoPB,false);
  1512.  
  1513.     p2cstr((unsigned char *)volname);
  1514.  
  1515.     while (strcmp(volname,dirname) != 0)
  1516.     {        
  1517.         infoPB.dirInfo.ioNamePtr = (unsigned char *)dirname;
  1518.         infoPB.dirInfo.ioVRefNum = the_vRefNum;
  1519.         infoPB.dirInfo.ioDrDirID = the_parID;
  1520.         infoPB.dirInfo.ioFDirIndex = -1;
  1521.         PBGetCatInfo(&infoPB,false);
  1522.         the_parID = infoPB.dirInfo.ioDrParID;
  1523.     
  1524.         p2cstr((unsigned char *)dirname);
  1525.         strcpy(path_copy,dirname);
  1526.         strcat(path_copy,":");
  1527.         strcat(path_copy,path);
  1528.         strcpy(path,path_copy);
  1529.     }
  1530. }
  1531.  
  1532. Boolean ReadPrefs (char *share_path)
  1533. {    OSErr err=noErr;
  1534.     short prefsFolder;
  1535.     Str255 prefsName="\pUAE Preferences";
  1536.     long prefDirID;
  1537.     short prefvRefNum;
  1538.     FSSpec spec;
  1539.     short home,preffile;
  1540.     Handle share_handle;
  1541.     Handle config_handle;
  1542.     int config_sets[128],count;
  1543.  
  1544.     home = CurResFile();
  1545.     preffile=0;
  1546.     *share_path=0;
  1547.     
  1548.     err=FindFolder(kOnSystemDisk, kPreferencesFolderType, true, &prefvRefNum, &prefDirID);
  1549.     if (err != noErr) return false;
  1550.     FSMakeFSSpec(prefvRefNum, prefDirID, prefsName, &spec);
  1551.  
  1552.     preffile=FSpOpenResFile(&spec, fsRdWrPerm);
  1553.     if (ResError() != noErr) return false;
  1554.  
  1555.     UseResFile(preffile);
  1556.  
  1557.     if (share_path != 0)
  1558.     {    share_handle = Get1Resource('STR ',128);
  1559.         if (ResError() == noErr && share_handle !=0 && *share_handle !=0)
  1560.         {    strcpy(share_path,*share_handle);
  1561.             ReleaseResource(share_handle);
  1562.         }
  1563.     }
  1564.  
  1565.     config_handle = Get1Resource('PREF',128);
  1566.     if (ResError() == noErr && config_handle !=0)
  1567.     {    BlockMove((Ptr) *config_handle,(Ptr) config_sets,128);
  1568.         ReleaseResource(config_handle);
  1569.         
  1570.         framerate=config_sets[0];
  1571.         use_slow_mem=config_sets[1];
  1572.         use_gfxlib=config_sets[2];
  1573.         automount_uaedev=config_sets[3];
  1574.         produce_sound=config_sets[4];
  1575.         fake_joystick=config_sets[5];
  1576.         screen_res=config_sets[6];
  1577.         use_quickdraw=config_sets[7];
  1578.         filesys_vRefNum=config_sets[8];
  1579.     }
  1580.  
  1581.     UseResFile(home);
  1582.     CloseResFile(preffile);
  1583.     return true;
  1584. }
  1585.  
  1586. void CreatePrefs (void)
  1587. {    OSErr err=noErr;
  1588.     short prefsFolder;
  1589.     Str255 prefsName="\pUAE Preferences";
  1590.     long prefDirID;
  1591.     short prefvRefNum;
  1592.     FSSpec spec;
  1593.     short home,preffile;
  1594.     
  1595.     home = CurResFile();
  1596.     preffile=0;
  1597.     
  1598.     err=FindFolder(kOnSystemDisk, kPreferencesFolderType, true, &prefvRefNum, &prefDirID);
  1599.     if (err != noErr) return;
  1600.     FSMakeFSSpec(prefvRefNum, prefDirID, prefsName, &spec);
  1601.     
  1602.     err=FSpCreate(&spec, 'mUAE', 'pref', 0);
  1603.     if (err != noErr) return;
  1604.     
  1605.     FSpCreateResFile(&spec, 'mUAE', 'pref', 0);
  1606. }
  1607.  
  1608. void WritePrefs (char *share_path)
  1609. {    OSErr err=noErr;
  1610.     short prefsFolder;
  1611.     Str255 prefsName="\pUAE Preferences";
  1612.     long prefDirID;
  1613.     short prefvRefNum;
  1614.     FSSpec spec;
  1615.     short home,preffile;
  1616.     Handle share_handle;
  1617.     Handle config_handle;
  1618.     int config_sets[128],count;
  1619.     
  1620.     home = CurResFile();
  1621.     preffile=0;
  1622.     
  1623.     err=FindFolder(kOnSystemDisk, kPreferencesFolderType, true, &prefvRefNum, &prefDirID);
  1624.     if (err != noErr) return;
  1625.     FSMakeFSSpec(prefvRefNum, prefDirID, prefsName, &spec);
  1626.     
  1627.     preffile=FSpOpenResFile(&spec, fsRdWrPerm);
  1628.     if (ResError() != noErr) return;
  1629.     
  1630.     for (count=0;count < 64;count++) config_sets[count]=0;
  1631.     
  1632.     config_sets[0]=framerate;
  1633.     config_sets[1]=use_slow_mem;
  1634.     config_sets[2]=my_use_gfxlib;
  1635.     config_sets[3]=my_automount_uaedev;
  1636.     config_sets[4]=produce_sound;
  1637.     config_sets[5]=fake_joystick;
  1638.     config_sets[6]=my_screen_res;
  1639.     config_sets[7]=my_use_quickdraw;
  1640.     config_sets[8]=filesys_vRefNum;
  1641.     
  1642.     UseResFile(preffile);
  1643.     
  1644.     
  1645.     if (share_path != 0)
  1646.     {    share_handle=Get1Resource('STR ',128);
  1647.         if (ResError() != noErr || share_handle == 0)
  1648.         {    share_handle=NewHandleClear(1024);
  1649.             strcpy(*share_handle,share_path);
  1650.             AddResource(share_handle,'STR ',128, "\pMac/Amiga sharing path");
  1651.             WriteResource(share_handle);
  1652.             DetachResource(share_handle);
  1653.         }
  1654.         else
  1655.         {    strcpy(*share_handle,share_path);
  1656.             ChangedResource(share_handle);
  1657.             WriteResource(share_handle);
  1658.             ReleaseResource(share_handle);
  1659.         }
  1660.     }
  1661.     
  1662.     config_handle=Get1Resource('PREF',128);
  1663.     if (ResError() != noErr || config_handle == 0)
  1664.     {    config_handle=NewHandleClear(1024);
  1665.         BlockMove((Ptr) config_sets,(Ptr) *config_handle,128);
  1666.         AddResource(config_handle,'PREF',128, "\pUAE Preferences");
  1667.         WriteResource(config_handle);
  1668.         DetachResource(config_handle);
  1669.     }
  1670.     else
  1671.     {    BlockMove((Ptr) config_sets,(Ptr) *config_handle,128);
  1672.         ChangedResource(config_handle);
  1673.         WriteResource(config_handle);
  1674.         ReleaseResource(config_handle);
  1675.     }
  1676.     
  1677.     UseResFile(home);
  1678.     CloseResFile(preffile);
  1679. }
  1680.